package emulator.hardware.nmos6502.operands;

import emulator.assembler.SymbolTable;
import emulator.hardware.HwByte;
import emulator.hardware.HwWord;
import emulator.hardware.debug.BusWatchException;
import emulator.hardware.memory.UnmappedMemoryException;
import emulator.hardware.nmos6502.Cpu6502;
import emulator.support.IndirectYOperandEval;
import emulator.support.OperandEval;
import emulator.util.MemoryPtr;

public class IndirectY extends ByteOperand {

	private HwWord abs_addr = new HwWord();
	private HwByte zp_addr;

	@Override
	public void init(Cpu6502 cpu) throws UnmappedMemoryException, BusWatchException {
		super.init(cpu);
		zp_addr = new HwByte(cpu.fetchProgramByte());
		abs_addr.setNumber(cpu.readWord((int) zp_addr.getNumber()));
		HwWord addr = new HwWord(abs_addr.getNumber());
		addr.add(cpu.getY());
		setAddress(addr);
	}

	@Override
	public int getByteCount() {
		return 1;
	}

	/* (non-Javadoc)
	 * @see emulator.hardware.nmos6502.operands.ByteOperand#getString()
	 */
	@Override
	public String getString() {
		return "($"+zp_addr+"),Y";
	}

	@Override
	public String getString(MemoryPtr mem_ref, SymbolTable symbols) {
		return "("+symbols.getLabelOrAddress(mem_ref.getByteOp())+"),Y";
	}

	@Override
	public int getExtraCycles() {
		if (!abs_addr.hi().equals(getAddress().hi()))
			return 4;
		return 3;
	}

	@Override
	public OperandEval getEvaluator(MemoryPtr mem_ref) {
		return new IndirectYOperandEval(mem_ref);
	}
}
